package com.wjj.sixinone.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wjj.sixinone.common.enums.ExceptionEnum;
import com.wjj.sixinone.common.enums.RedisConstantEnum;
import com.wjj.sixinone.common.exception.GlobalException;
import com.wjj.sixinone.common.pojo.entity.BanIp;
import com.wjj.sixinone.common.pojo.entity.User;
import com.wjj.sixinone.common.pojo.excel.BanIpExcel;
import com.wjj.sixinone.common.pojo.vo.IpVO;
import com.wjj.sixinone.common.util.AuthContextUtil;
import com.wjj.sixinone.common.util.CurrentIpUtils;
import com.wjj.sixinone.common.util.Result;
import com.wjj.sixinone.handler.ExcelExportHandle;
import com.wjj.sixinone.service.IpService;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class IpBanServiceImpl implements IpService {



    private final RedisTemplate<String, String> redisTemplate;
    private final ObjectMapper objectMapper;
    private final ExcelExportHandle exportHandle;

    public IpBanServiceImpl(RedisTemplate<String, String> redisTemplate, ObjectMapper objectMapper, ExcelExportHandle exportHandle) {
        this.redisTemplate = redisTemplate;
        this.objectMapper = objectMapper;
        this.exportHandle = exportHandle;
    }

    @Override
    public Result getIp(Map map) {
        return null;
    }

    @Override
    public Result banIp(Map<String, String> map) {
        String ip = map.get("ip");
        String reason = map.get("reason");

        // 检查是否已经封禁该IP
        String banIpJson = redisTemplate.opsForValue().get(RedisConstantEnum.BAN_IP.getKey() + ip);
        if (banIpJson != null) {
            throw new GlobalException(ExceptionEnum.ALREDY_BAN_IP);
        }

        BanIp banIp = new BanIp();
        banIp.setIp(ip);
        String userIP = CurrentIpUtils.getUserIP();
        if (userIP != null) {
            banIp.setUserIp(userIP);
        }
        User user = AuthContextUtil.get();
        if (user != null) {
            banIp.setBanUser(user.getUsername());
        }
        banIp.setBanTime(LocalDateTime.now());
        banIp.setBanReason(reason);

        try {
            String newBanIpJson = objectMapper.writeValueAsString(banIp);
            redisTemplate.opsForValue().set(RedisConstantEnum.BAN_IP.getKey() + ip, newBanIpJson);
            return Result.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(ExceptionEnum.INSERT_ERROR.getStatus(), ExceptionEnum.INSERT_ERROR.getMessage());
        }
    }

    @Override
    public Result getAllBannedIps(IpVO ipVO) {
        List<BanIp> bannedIps = getAllBannedIps();

        // 条件过滤
        List<BanIp> filteredIps = bannedIps.stream()
                .filter(banIp -> {
                    boolean matches = true;
                    if (ipVO.getUserName() != null && !ipVO.getUserName().isEmpty()) {
                        matches = banIp.getBanUser().contains(ipVO.getUserName());
                    }
                    if (ipVO.getIp() != null && !ipVO.getIp().isEmpty()) {
                        matches = matches && banIp.getIp().contains(ipVO.getIp());
                    }
                    return matches;
                })
                .collect(Collectors.toList());

        // 分页逻辑
        int total = filteredIps.size();
        int start = Math.max(0, ipVO.getPage() * ipVO.getLimit());
        int end = Math.min(start + ipVO.getLimit(), total);

        if (start >= end) {
            return Result.ok().put("data",filteredIps).put("count", total);
        }

        List<BanIp> pageResult = filteredIps.subList(start, end);

        return Result.ok().put("data", pageResult).put("count", total);
    }

    @Override
    public Result deletByIp(Map<String, String> map) {
        String ip = map.get("ip");
        Boolean delete = redisTemplate.delete(RedisConstantEnum.BAN_IP.getKey() + ip);
        if (delete==null||!delete) {
            throw new GlobalException(ExceptionEnum.DELETE_ERROR);
        }
        return Result.ok();
    }

    @Override
    public void uploadExcel(HttpServletResponse response) {
        List<BanIpExcel>banIpExcels=new ArrayList<>();
        List<BanIp> allBannedIps = getAllBannedIps();
        for (BanIp bannedIp : allBannedIps) {
            BanIpExcel banIpExcel=new BanIpExcel();
            BeanUtils.copyProperties(bannedIp,banIpExcel);

            banIpExcels.add(banIpExcel);
        }
        exportHandle.export(response,"封禁IP",banIpExcels,BanIpExcel.class);


    }
    private List<BanIp>getAllBannedIps(){
        List<BanIp> bannedIps = new ArrayList<>();
        try {
            // 获取所有匹配封禁IP的键
            Set<String> keys = redisTemplate.keys(RedisConstantEnum.BAN_IP.getKey() + "*");
            if (keys != null && !keys.isEmpty()) {
                for (String key : keys) {
                    // 获取每个键对应的值
                    String banIpJson = redisTemplate.opsForValue().get(key);
                    if (banIpJson != null) {
                        // 将JSON字符串反序列化为BanIp对象
                        BanIp banIp = objectMapper.readValue(banIpJson, BanIp.class);
                        bannedIps.add(banIp);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bannedIps;
    }

}

